﻿using System;
using ZCConsole.VOBC;
using System.Net;
using ZCATSMes;
using System.IO;
using System.Diagnostics;

namespace ZCConsole
{
    class HandleData
    {
        string off = " ";

        private byte[] Data;
        private Unpack UnPackage;
        string consoleConcentToATP;
        string consoleFromATP;
        MySerialize MySer = new MySerialize();

        internal HandleVobc VOBC = new HandleVobc();
        private ZC zc;
        private ZCSocket zcSock;
        public UpdateRoute updateRoute = new UpdateRoute();
        public UpdateTrainPosition updateTrain;


        public HandleData(ZC zc)
        {
            this.zc = zc;
            updateTrain = new UpdateTrainPosition(zc);
        }

        public void Handle(byte[] data, ZC zc, ZCSocket zcSock)
        {
            this.zcSock = zcSock;
            this.Data = data;
            AnalysisHead();
        }

        /// <summary>
        /// 解包，分析包头数据信息
        /// </summary>
        private void AnalysisHead()
        {
            UnPackage = new Unpack();
            UnPackage.Reset(Data);
            JudgeDevice(new PacketHeader()
            {
                CycleNumber = UnPackage.GetUint16(),       //获取周期序号
                Type = (DataType)UnPackage.GetUint16(),    //获取数据信息类型
                SenderID = (DeviceID)UnPackage.GetByte(),  //获取发送设备ID
                ReceiveID = (DeviceID)UnPackage.GetByte(), //获取接收设备ID
                DataLength = UnPackage.GetUint16()         //获取应用数据长度
            }, zc);
        }

        /// <summary>
        /// 判断并处理数据包过程
        /// </summary>
        /// <param name="head"></param>
        /// <param name="zc"></param>
        private void JudgeDevice(PacketHeader head, ZC zc)
        {
            if (head.SenderID == DeviceID.ATP1 || head.SenderID == DeviceID.ATP2 || head.SenderID == DeviceID.ATP3 || head.SenderID == DeviceID.ATP4)
            //数据包来自ATP
            {
                VOBC.UnPack(UnPackage, zc);
                ConsoleOut(VOBC.trainInfo, null, false);

                if (VOBC.trainInfo.NcTrain == NCTrain.QuitCBTCLogOutZC)
                //列车注销
                {
                    ATPPackage InfoSendToATP = new ATPPackage();
                    InfoSendToATP.NC_ZC = 0x03;
                    VOBCQuit Quit = new VOBCQuit(VOBC.trainInfo, zc, updateRoute, updateTrain);
                    updateTrain.PreTrainPosition.Remove(VOBC.trainInfo.NIDTrain);
                    updateRoute.PreAccess.Remove(VOBC.trainInfo.NIDTrain);
                    InfoSendToATP.PackATP();

                    //ZC2ATS infoToATS = new ZC2ATS();
                    //new ATS.PackToATS(infoToATS, VOBC.trainInfo, InfoSendToATP, true);
                    //zcSock.Send(MySer.serializeObject(infoToATS), MySer.serializeObject(infoToATS).Length, (int)DeviceID.ATS);
                }

                else if (VOBC.trainInfo.NcTrain == NCTrain.AskMA)
                //请求MA
                {
                    updateTrain.SetTrainInfo(VOBC.trainInfo);
                    InfoSendToATP infoSendToATP = new InfoSendToATP(VOBC.trainInfo, head.SenderID, zc);
                    updateRoute.SetTrainInfoAndMa(VOBC.trainInfo, infoSendToATP.MA);
                    infoSendToATP.atpPackage.PackATP();
                    zcSock.Send(infoSendToATP.atpPackage.ATPPack.buf_, infoSendToATP.atpPackage.ATPPack.byteFlag_, (int)head.SenderID);

                    //ZC2ATS infoToATS = new ZC2ATS();
                    //new ATS.PackToATS(infoToATS, VOBC.trainInfo, infoSendToATP.atpPackage, false);
                    //if (!off.Equals(infoToATS.TrainId + "#" + infoToATS.PositionId + "#" + infoToATS.Offset))
                    //{
                    //    off = infoToATS.TrainId + "#" + infoToATS.PositionId + "#" + infoToATS.Offset + "#" + infoToATS.Direction;
                    //    Debug.WriteLine(off);
                    //}
                    //zcSock.Send(MySer.serializeObject(infoToATS), MySer.serializeObject(infoToATS).Length, (int)DeviceID.ATS);
                    ConsoleOut(VOBC.trainInfo, infoSendToATP, true);
                }
            }

            else if (head.SenderID == DeviceID.CI1 || head.SenderID == DeviceID.CI2 || head.SenderID == DeviceID.CI3 || head.SenderID == DeviceID.CI4)
            //数据包来自联锁
            {
                CI.HandleCIData CI = new CI.HandleCIData(UnPackage, head.SenderID, zc);
                CI.PackToCI packToCI = new CI.PackToCI(head.SenderID, CI, zc);
                zcSock.Send(packToCI.CIPacket.buf_, packToCI.CIPacket.byteFlag_, (int)head.SenderID);
                zcSock.SendLogicSections(packToCI.CIPacket.buf_, packToCI.CIPacket.byteFlag_);
            }
        }

        private void ConsoleOut(TrainInfo trainInfo, InfoSendToATP infoSendToATP, bool isComplete)
        {
            string content = null;
            if (!isComplete)
            {
                content = "Receive from ATP:"
                            + "\r\n" + "NID_Train：" + trainInfo.NIDTrain +
                            " NC_Train：" + trainInfo.NcTrain +
                            " HeadPosition：" + (trainInfo.HeadPosition is Section ? trainInfo.HeadPosition.Name : ((trainInfo.HeadPosition as RailSwitch).section.Name + "-" + (trainInfo.HeadPosition as RailSwitch).Name)) + "+" + trainInfo.HeadOffset +
                            " TailPosition：" + (trainInfo.TailPosition is Section ? trainInfo.TailPosition.Name : ((trainInfo.TailPosition as RailSwitch).section.Name + "-" + (trainInfo.TailPosition as RailSwitch).Name)) + "+" + trainInfo.TailOffset +
                            " Speed:" + trainInfo.Speed + " Direction:" + (trainInfo.TrainDirection == TrainDir.Right ? "Up" : "Down") + " PSDoor:" + (trainInfo.PSDoor ? "Open" : "Close") +
                            "\r\n";
                ZC.AllocConsole();
                if (content != consoleFromATP)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine(content);
                    consoleFromATP = content;
                    OutPutLogs(consoleFromATP);
                }
            }
            else
            {
                content = "Send to ATP:" + "\r\n" +
                            "NC_ZC:" + infoSendToATP.atpPackage.NC_ZC + " MALength:" + infoSendToATP.atpPackage.N_Length +
                            " EndMA:" + (infoSendToATP.MA.MAEndDevice is Section ? infoSendToATP.MA.MAEndDevice.Name : (infoSendToATP.MA.MAEndDevice == null ? "null" : ((infoSendToATP.MA.MAEndDevice as RailSwitch).section.Name) + "-" + infoSendToATP.MA.MAEndDevice.Name)) +
                            " EndMAOffset:" + infoSendToATP.atpPackage.D_MATailOff +
                            " NumOfObstacle:" + infoSendToATP.atpPackage.N_Obstacle + "  {  ";
                foreach (var item in infoSendToATP.atpPackage.Obstacle)
                {
                    RailSwitch obsta = zc.data.Devices.Find((Device element) =>
                    {
                        if (element is RailSwitch)
                        {
                            return (element as RailSwitch).Id == item.NID_Obstacle;
                        }
                        return false;
                    }) as RailSwitch;

                    content += obsta.section.Name + "-" + obsta.Name + "(" + item.Q_Obstacle_Now + ")  ";
                }

                content = content + "}" + "\r\n";
                ZC.AllocConsole();
                if (content != consoleConcentToATP)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine(content);
                    consoleConcentToATP = content;
                    OutPutLogs(consoleConcentToATP);
                }
            }

        }

        private void OutPutLogs(string content)
        {
            if (zc.IsSaveLog)
            {
                string path = "Log\\" + DateTime.Now.Year + " " + DateTime.Now.Month + "." + DateTime.Now.Day + ".txt";
                File.AppendAllText(path, content);
            }
        }

    }
}
